home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
EnigmA Amiga Run 1995 October
/
EnigmA AMIGA RUN 01 (1995)(G.R. Edizioni)(IT)[!][issue 1995-10][Aminet 7].iso
/
Aminet
/
misc
/
emu
/
prlink_amiga.lha
/
prlink-0.8.0a
/
src
/
prtrans8.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-04-06
|
4KB
|
189 lines
#ifdef __linux__
#include <unistd.h>
#include <asm/io.h>
#endif /* __linux__ */
#include "prtrans.h"
unsigned baseaddr, stataddr, ctrladdr;
unsigned ack;
int prinit (void) {
#ifdef __linux__
if (ioperm (baseaddr, 3, 1))
return -1;
#endif /* __linux__ */
outb(8, baseaddr); /* set the -FLAG signal to high */
stataddr = baseaddr + 1;
ctrladdr = baseaddr + 2;
ack = 0x80 & inb(stataddr); /* get the current state of the BUSY line */
return 0;
}
void prclose (void) {
}
void output (unsigned char byte) {
send (&byte, 1);
}
unsigned input (void) {
unsigned char byte;
receive (&byte, 1);
return byte;
}
unsigned wait_input (void) {
register unsigned char data;
outb(4, ctrladdr); /* set the bidirectional signals to input */
outb(0, baseaddr); /* drop -FLAG */
while (ack == (0x80 & inb(stataddr))) /* wait for -BUSY to change */
usleep (SLEEP_TIME); /* wait before retrying */
outb(8, baseaddr); /* raise -FLAG */
data = inb(ctrladdr) & 0x0f; /* read the low nybble */
outb(0, baseaddr); /* drop -FLAG */
while (ack != (0x80 & inb(stataddr))); /* wait for -BUSY to change */
data |= inb(ctrladdr) << 4; /* read the high nybble */
outb(8, baseaddr); /* raise -FLAG */
return data ^ 0xbb;
}
#if !defined(__i386__) && !defined(__GNU_C__)
void send (unsigned char *buffer, unsigned length) {
register unsigned char byte;
while (length--) {
byte = *buffer++ ^ 0x0b; /* invert bits 0, 1 and 3 */
outb(byte, ctrladdr);
outb(byte & ~8, baseaddr); /* drop the -FLAG to low */
while (ack == (0x80 & inb(stataddr))); /* wait for BUSY to change */
outb(8, baseaddr); /* raise -FLAG again */
ack ^= 0x80; /* store the new state of -BUSY */
}
}
#else /* __i386__ && __GNU_C__ */
void send (unsigned char *buffer, unsigned length) {
asm ("push %%ebp
movw _baseaddr,%%dx
movl %1,%%ecx
movl %0,%%ebp
sloop: movb (%%ebp),%%al
xorb $0xb,%%al
movb _ack,%%ah
addw $2,%%dx
outb %%al,%%dx
subw $2,%%dx
andb $0xf7,%%al
outb %%al,%%dx
incw %%dx
owait: inb %%dx,%%al
andb $0x80,%%al
cmpb %%al,%%ah
je owait
decw %%dx
xorb $0x80,%%ah
movb %%ah,_ack
movb $8,%%al
outb %%al,%%dx
inc %%ebp
loop sloop
pop %%ebp"
: /* no outputs */
: "g" (buffer), "g" (length)
: "ax", "ecx", "dx");
}
#endif /* __i386__ && __GNU_C__ */
#if !defined(__i386__) && !defined(__GNU_C__)
void receive (unsigned char *buffer, unsigned length) {
register unsigned char data;
while (length--) {
outb(4, ctrladdr); /* set the bidirectional signals to input */
outb(0, baseaddr); /* drop -FLAG */
while (ack == (0x80 & inb(stataddr))); /* wait for -BUSY to change */
outb(8, baseaddr); /* raise -FLAG */
data = inb(ctrladdr) & 0x0f; /* read the low nybble */
outb(0, baseaddr); /* drop -FLAG */
while (ack != (0x80 & inb(stataddr))); /* wait for -BUSY to change */
data |= inb(ctrladdr) << 4; /* read the high nybble */
outb(8, baseaddr); /* raise -FLAG */
*buffer++ = data ^ 0xbb;
}
}
#else /* __i386__ && __GNU_C__ */
void receive (unsigned char *buffer, unsigned length) {
asm ("push %%ebp
movw _baseaddr,%%dx
movl %1,%%ecx
movl %0,%%ebp
rloop: xorb %%al,%%al
outb %%al,%%dx
incw %%dx
iwait1: inb %%dx,%%al
andb $0x80,%%al
cmpb _ack,%%al
je iwait1
decw %%dx
movb $8,%%al
outb %%al,%%dx
addw $2,%%dx
movb $4,%%al
outb %%al,%%dx
inb %%dx,%%al
and $0xf,%%al
movb %%al,(%%ebp)
subw $2,%%dx
xorb %%al,%%al
outb %%al,%%dx
incw %%dx
iwait2: inb %%dx,%%al
andb $0x80,%%al
cmpb _ack,%%al
jne iwait2
decw %%dx
movb $8,%%al
outb %%al,%%dx
addw $2,%%dx
inb %%dx,%%al
subw $2,%%dx
salb $4,%%al
orb (%%ebp),%%al
xorb $0xbb,%%al
movb %%al,(%%ebp)
inc %%ebp
loop rloop
pop %%ebp"
: /* no outputs */
: "g" (buffer), "g" (length)
: "ax", "ecx", "dx");
}
#endif /* __i386__ && __GNU_C__ */